/* Developed by Vinh, Nguyen Hong <mansofta@gmail.com>
 * Copyright HIENDAI SOFTWARE COMPANY 2004
 * http://www.hiendai.com.vn
 * contact@hiendai.com.vn
*/
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Collections;

namespace MarcXmlParser {

	public class CDatafield
	{	
	protected	XmlDocument ptCurrentDoc;
	protected	XmlNode ptCurrentRootNode;			
	public CDatafield()
		{
			ptCurrentDoc=new XmlDocument();				
			ptCurrentDoc.LoadXml("<datafield tag='999' ind1='' ind2=''></datafield>"); 
			ptCurrentRootNode=ptCurrentDoc.SelectSingleNode("./*[local-name() ='datafield']"); 		
		}
	public void Sort()
		{
			ArrayList SfAL=new ArrayList();
			CSubfields Sfs=new CSubfields(ptCurrentRootNode);
			for(int i=0;i<Sfs.Count;i++)
			{
				SfAL.Add(Sfs.Subfield(i).OuterXml);
				Sfs.Remove(i);
			}
			SfAL.Sort();
			for(int i=0;i<SfAL.Count;i++)
			{
				CSubfield Sf=new CSubfield();
				Sf.load_Xml(SfAL[i].ToString());
				Sfs.Add(Sf);
			}
			SfAL.Clear();
		}

    public void ReConstruct()
		{
			ptCurrentDoc.LoadXml("<datafield tag='999' ind1='' ind2=''></datafield>"); 
			ptCurrentRootNode=ptCurrentDoc.SelectSingleNode("./*[local-name() ='datafield']"); 				
		}
	public bool load_RootNode(ref XmlNode ptDatafieldNode)
		{
			ptCurrentRootNode=ptDatafieldNode;			
			if(ptCurrentRootNode.Name=="datafield")
				return true;
			else
				return false;// invalid node name
		}
	public bool load_Xml(String DatafieldXml)
		{
			ptCurrentDoc.LoadXml(DatafieldXml);
			ptCurrentRootNode=ptCurrentDoc.SelectSingleNode("./*[local-name() ='datafield']");
			if (ptCurrentRootNode!=null)
				return true;
			else
				return false;
		}
	public String Tag
	 {
		 set
		 {
			XmlElement xElem;//Data field node			
			xElem=(XmlElement)(ptCurrentRootNode); 
			xElem.SetAttribute("tag", value);		
		 }
		 get
		 {
			XmlNode mxNode = (XmlNode)(ptCurrentRootNode.Attributes.GetNamedItem("tag"));
            if (mxNode != null)
				return ((XmlAttribute)(mxNode)).Value;
			else
				return "";		 
		 }	 
	 }
	public String Ind1
	 {
		 set
		 {
			XmlElement xElem;//Data field node			
			xElem=(XmlElement)(ptCurrentRootNode); 
			xElem.SetAttribute("ind1", value);				 
		 }
		 get
		 {
			XmlNode mxNode = (XmlNode)(ptCurrentRootNode.Attributes.GetNamedItem("ind1"));
            if (mxNode != null)
				return ((XmlAttribute)(mxNode)).Value;
			else
				return " ";		 
		 }	 
	 }

	 public String Ind2
	 {
		 set
		 {
			XmlElement xElem;//Data field node			
			xElem=(XmlElement)(ptCurrentRootNode); 
			xElem.SetAttribute("ind2", value);				 
		 }
		 get
		 {
			XmlNode mxNode = (XmlNode)(ptCurrentRootNode.Attributes.GetNamedItem("ind2"));
            if (mxNode != null)
				return ((XmlAttribute)(mxNode)).Value;
			else
				return " ";		 
		 }	 
	 }
	 public String OuterXml
	 {
		get
		{
			return ptCurrentRootNode.OuterXml;  			
		}
	 }
	 public String InnerText
	 {
		get
		{
			return ptCurrentRootNode.InnerText;			
		}
	 }
	public XmlNode RootNode
	{
		set
		{
			ptCurrentRootNode=value;
			ptCurrentDoc=ptCurrentRootNode.OwnerDocument;
		}			
		get
		{
			return ptCurrentRootNode;
		}			
	}
	public CSubfields Subfields
	{
		get
		{
			return new CSubfields(ptCurrentRootNode);
		}
	}
	public String SubfieldsText
	{
		get
		{
			StringBuilder SfsString = new StringBuilder();
			CSubfields SubfieldList;
			SubfieldList= new CSubfields(ptCurrentRootNode);
			if (SubfieldList.Count>0)//have some subfields
			{
				for(int i=0; i<SubfieldList.Count;++i)
				{
					SfsString.Append("$");
					SfsString.Append(SubfieldList.Subfield(i).Code);
					SfsString.Append(SubfieldList.Subfield(i).Value);				
				}
			}
			return SfsString.ToString();		
		}
		set
		{
            string SubfieldsString = value;
			String delimStr = "$";
			Char[] delimiter = delimStr.ToCharArray();			
			//int iCount=0;
			int k;
			CSubfield Sf;
			CSubfields Sfs;
			String[] split;
			IEnumerator myEnum;
	  	    Sfs=this.Subfields;
			//remove all current subfield in the subfield list
			for(int j=0; j<Sfs.Count;++j)
			{
				Sfs.Remove(j); 
			}
			split = SubfieldsString.Split(delimiter);
			myEnum = split.GetEnumerator();
			k=split.Length;
			if(k==1)//only data no subfield delimiter
			{
				 if(SubfieldsString.Length>0)//have some data
				 {
					// create new Sf with code=a
					Sf=new CSubfield();
					Sf.Code="a";
					Sf.Value=SubfieldsString; 
					Sfs=this.Subfields; 
					Sfs.Add(Sf);
				 }
			}else
			{
				Sfs=this.Subfields; 				
				Sf=new CSubfield();
				myEnum.MoveNext();
				String s = (String)(myEnum.Current);				
				if(s.Length>1)
				{					
					Sf.ReConstruct();
					Sf.Code=s.Substring(0,1);				
					Sf.Value=s.Substring(1);				
					Sfs.Add(Sf); 
				}				
				while(myEnum.MoveNext())
				{
					s=(String)(myEnum.Current);
					if(s.Length>1)
					{
						Sf.ReConstruct();
						Sf.Code=s.Substring(0,1);				
						Sf.Value=s.Substring(1);				
						Sfs.Add(Sf); 													
					}
				}
			}			
		}
	 }

    public String get_SubfieldsText(string sepchars)
    {
            //this.Sort();
            StringBuilder SfsString = new StringBuilder();
            CSubfields SubfieldList;
            SubfieldList = new CSubfields(ptCurrentRootNode);
            if (SubfieldList.Count > 0)//have some subfields
            {
                for (int i = 0; i < SubfieldList.Count; ++i)
                {
                    if(i>0) SfsString.Append(sepchars);
                    //SfsString.Append(SubfieldList.Subfield(i).Code);
                    SfsString.Append(SubfieldList.Subfield(i).Value);
                }
            }
            return SfsString.ToString();
    }
	};
}
